﻿using System;
using System.Windows.Controls;
using System.Collections.Generic;
using WiMo.Games.Drawables;
using System.Windows;
using System.Threading;
using System.Windows.Media;
using WiMo.Games.Silverlight.Drawing.Drawables;
using WiMo.Games.Drawing.WP7S.Drawables;
using WiMo.Games.Drawing.Silverlight.Drawables;

namespace WiMo.Games.Drawing.WP7S
{
    public class DisplayManager : IDisplay
    {
        private Canvas _host;
        private AutoResetEvent _keyAccess;
        public bool Diagnostics { get; set; }

        public DisplayStrategies DisplayStrategy { get; set; }

        public DisplayManager(Canvas control, Size targetSize, Size actualSize, int dpi)
        {
            TargetSize = targetSize;
            Size = actualSize;
            ScaleFactor = Vector2.One;
            _sprites = new List<IDrawable>();
            _tempObjects = new List<IDrawable>();
            _host = control;
            _keyAccess = new AutoResetEvent(true);
            ScaleFactor = new Vector2((float)actualSize.Width / (float)targetSize.Width, (float)actualSize.Height / (float)targetSize.Height);
        }

        public Size Size { get; private set; }
        public Size TargetSize { get; private set; }
        public Vector2 ScaleFactor { get; private set; }
        public byte AspectRatio { get; set; }
        public int DPI { get; set; }

        private List<IDrawable> _sprites;
        private List<IDrawable> _tempObjects;
        public Location DisplayOffset { get; set; }

        private SpriteImage _backgroundImage = null;
        public ITexture BackgroundImage
        {
            get
            {
                return _backgroundImage.TextureList[0];
            }
            set
            {
                if (value == null)
                    _backgroundImage = null;
                else
                {
                    _backgroundImage = new SpriteImage();
                    _backgroundImage.Origin = Origin.TopLeft;
                    _backgroundImage.Scale = ScaleFactor;
                    _backgroundImage.AddImage(value);
                }
            }
        }

        public string Name
        {
            get { return "Silverlight Display Manager"; }
        }

        public Color BackgroundColor { get; set; }

        public void Reset()
        {
            _keyAccess.WaitOne();

            _sprites.Clear();
            
            foreach (var tempObject in _tempObjects)
                tempObject.Dispose();

            _tempObjects.Clear();

            _keyAccess.Set();
        }

        public void Add(IDrawable drawable)
        {
            _keyAccess.WaitOne();
            _sprites.Add(drawable);
            _keyAccess.Set();
        }

        public ISpriteLine DrawLine(Location start, Location end, Color color, int width)
        {
            SpriteLine line = SpriteLine.CreateLine(start, end, ScaleFactor, color, width);

            _sprites.Add(line);
            _tempObjects.Add(line);

            return line;
        }

        public ISpriteText DrawText(PointF position, string text, ISpriteFont font, Color foreColor)
        {
            return DrawText(position, text, font, foreColor, Origin.TopLeft);
        }

        public ISpriteText DrawText(PointF position, string text, ISpriteFont font, Color foreColor, Origin origin)
        {
            var spriteText = SpriteText.Create(position, ScaleFactor, text, font, foreColor, origin);

            _sprites.Add(spriteText);
            _tempObjects.Add(spriteText);

            return spriteText;
        }

        public ISpriteShape DrawRectangle(Rectangle rect, Color color, int width)
        {
            var spriteRect = SpriteShape.CreateRectangle(rect, ScaleFactor, color, width);

            _sprites.Add(spriteRect);
            _tempObjects.Add(spriteRect);

            return spriteRect;
        }

        public ISpriteShape DrawRectangle(Rectangle rect, Color color, int width, Origin origin)
        {
            SpriteShape spriteRect = SpriteShape.CreateRectangle(rect, ScaleFactor, color, width, origin);

            _sprites.Add(spriteRect);
            _tempObjects.Add(spriteRect);

            return spriteRect;
        }

        public ISpriteShape DrawCircle(PointF position, int radius, Color borderColor, int width)
        {
            SpriteShape spriteCircle = SpriteShape.CreateCircle(position, ScaleFactor, radius, borderColor, width); ;

            _sprites.Add(spriteCircle);
            _tempObjects.Add(spriteCircle);

            return spriteCircle;
        }

        public ISpriteShape FillRectangle(Rectangle rect, Color fillColor, Color borderColor, int width)
        {
            SpriteShape spriteRect = SpriteShape.CreateRectangle(rect, ScaleFactor, fillColor, borderColor, width);

            _sprites.Add(spriteRect);
            _tempObjects.Add(spriteRect);

            return spriteRect;
        }

        public ISpriteShape FillRectangle(Rectangle rect, Color fillColor, Color borderColor, int width, Origin origin)
        {
            SpriteShape spriteRect = SpriteShape.CreateRectangle(rect, ScaleFactor, fillColor, borderColor, width, origin); ;

            _sprites.Add(spriteRect);
            _tempObjects.Add(spriteRect);

            return spriteRect;
        }

        public ISpriteShape FillCircle(PointF position, int radius, Color fillColor, Color borderColor, int width)
        {
            SpriteShape spriteCircle = SpriteShape.CreateCircle(position, ScaleFactor, radius, borderColor, width); ;

            _sprites.Add(spriteCircle);
            _tempObjects.Add(spriteCircle);

            return spriteCircle;
        }

        public void Render(ISpriteImage sprite)
        {
            _host.Children.Add(sprite.DrawInformation as UIElement);
        }

        public void Render(ISpriteText text)
        {
            _host.Children.Add(text.DrawInformation as UIElement);
        }

        public void Render(ISpriteShape shape)
        {
            _host.Children.Add(shape.DrawInformation as UIElement);
        }

        public void Render(ISpriteLine line)
        {
            _host.Children.Add(line.DrawInformation as UIElement);
        }

        public ISpriteShape CreateEllipse()
        {
            return new Ellipse();
        }

        public ISpriteShape CreatePolygon()
        {
            return new Polygon();
        }

        public ISpriteShape CreateLineList()
        {
            return new LineList();
        }

        public ISpriteImage CreateSpriteImage()
        {
            return new SpriteImage();
        }

        public ISpriteLine CreateLine()
        {
            throw new NotImplementedException();
        }

        public ISpriteShape CreateRectangle()
        {
            return new Drawables.Rectangle();
        }

        public ISpriteText CreateText()
        {
            return new SpriteText();
        }

        public void Render()
        {
            _keyAccess.WaitOne();
            
            _host.Background = new System.Windows.Media.SolidColorBrush(BackgroundColor.GetMediaColor());
            _host.Children.Clear();

            if (_backgroundImage != null)
                _backgroundImage.Render(this);

            foreach (var sprite in _sprites)
            {
                if(sprite.IsVisible)
                    sprite.Render(this);
            }

            _keyAccess.Set();
        }

        public void Invalidate()
        {

        }

        public void Resize(Size bounds)
        {
            
        }


        public void Dispose()
        {
            throw new NotImplementedException();
        }
    }
}
